// 2025/08/13
// Author: Forever
#include <bits/stdc++.h>
using namespace std;
#define int __uint128_t
#define get(x) (x == 0 ? n : m)
const int N = 1001;
int n, m, num[2][N], cnt[2];
bool use[2][N];

template <typename T>
T read()
{
    T x = 0, f = 1;
    char c = getchar();
    while (!isdigit(c))
        f = c == '-' ? -1 : 1, c = getchar();
    while (isdigit(c))
        x = x * 10 + (c - '0'), c = getchar();
    return x * f;
}

template <typename T>
void write(T x)
{
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}

struct Segment {
private:
    int a[4 * N + 5];
    void build(int pos, int x, int l, int r)
    {
        if (l == r) {
            a[pos] = num[type][x] / __gcd(num[!type][l], num[type][x]);
            return;
        }
        int mid = (l + r) >> 1;
        build(pos << 1, x, l, mid);
        build(pos << 1 | 1, x, mid + 1, r);
        a[pos] = __gcd(a[pos << 1], a[pos << 1 | 1]);
    }
    void clear(int pos, int l, int r, int x)
    {
        if (l == r) {
            a[pos] = 0;
            return;
        }
        int mid = (l + r) >> 1;
        if (x <= mid)
            clear(pos << 1, l, mid, x);
        else
            clear(pos << 1 | 1, mid + 1, r, x);
        a[pos] = __gcd(a[pos << 1], a[pos << 1 | 1]);
    }

public:
    bool type;
    void build(int x)
    {
        build(1, x, 1, get(!type));
    }
    void clear(int x)
    {
        clear(1, 1, get(!type), x);
    }
    bool check()
    {
        return a[1] == 1;
    }
} seg[2][N];

void solve()
{
    memset(use, 0, sizeof(use));
    cnt[0] = cnt[1] = 0;
    n = read<int>(), m = read<int>();
    for (int i = 0; i < 2; i++)
        for (int j = 1; j <= get(i); j++)
            num[i][j] = read<int>();
    sort(num[0] + 1, num[0] + n + 1);
    sort(num[1] + 1, num[1] + m + 1);
    queue<pair<bool, int>> q;
    for (int i = 0; i < 2; i++)
        for (int j = 1; j <= get(i); j++) {
            seg[i][j].type = i, seg[i][j].build(j);
            if (!seg[i][j].check())
                q.push({ i, j }), use[i][j] = 1, cnt[i]++;
        }
    while (!q.empty()) {
        auto [type, x] = q.front();
        q.pop();
        for (int i = 1; i <= get(!type); i++) {
            if (use[!type][i])
                continue;
            seg[!type][i].clear(x);
            if (seg[!type][i].check())
                continue;
            use[!type][i] = 1, cnt[!type]++;
            q.push({ !type, i });
        }
    }
    if (cnt[0] == n || cnt[1] == m) {
        puts("NO");
        return;
    }
    puts("YES");
    write(n - cnt[0]), putchar(' '), write(m - cnt[1]);
    putchar('\n');
    for (int i = 0; i < 2; i++) {
        for (int j = 1; j <= get(i); j++)
            if (!use[i][j])
                write(num[i][j]), putchar(' ');
        putchar('\n');
    }
}

signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = read<int>();
    while (t--)
        solve();
    return 0;
}